{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### MCP Deep dive\n",
    "\n",
    "Creating and using own MCP Server and MCP Client!\n",
    "\n",
    "It's pretty simple, but it's not super-simple. The excitment around MCP is about how easy it is to share and use other MCP Servers - making our own does involve a bit of work.\n",
    "\n",
    "Let's review some python code made mostly by a hard-working Engineering Team:\n",
    "\n",
    "accounts.py"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Importing required libraries\n",
    "\n",
    "from agents import Agent, Runner, trace\n",
    "from agents.mcp import MCPServerStdio\n",
    "from dotenv import load_dotenv\n",
    "from IPython.display import Markdown, display\n",
    "\n",
    "# importing python class from accounts.py\n",
    "from accounts import Account"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "load_dotenv(override=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "account = Account.get(\"Ian\")\n",
    "account"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "account.buy_shares(\"AMZN\", 4, \"The bookstore looks promising in the future.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "account.report()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "account.list_transactions()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Writing an MCP server and using it directly!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Using accounts server as an MCP server\n",
    "\n",
    "params = {\n",
    "    \"command\": \"uv\", \n",
    "    \"args\": [\"run\", \"accounts_server.py\"]\n",
    "    }\n",
    "\n",
    "async with MCPServerStdio(params=params, client_session_timeout_seconds=30) as server:\n",
    "    mcp_tools = await server.list_tools()\n",
    "\n",
    "mcp_tools"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from agents.extensions.models.litellm_model import LitellmModel\n",
    "import os"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "api_key = os.getenv(\"AMAZON_BEDROCK_API_KEY\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "instructions = \"You are able to manage an account for a client, and answer questions about the account.\"\n",
    "request = \"My name is Ian and my account is under the name Ian. What's my balance and my holdings?\"\n",
    "model_name = \"us.amazon.nova-micro-v1:0\"\n",
    "model=LitellmModel(model=model_name, api_key=api_key)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "async with MCPServerStdio(params=params, client_session_timeout_seconds=60) as mcp_server:\n",
    "    agent = Agent(\n",
    "        name=\"account_manager\",\n",
    "        model=model,\n",
    "        instructions=instructions,\n",
    "        mcp_servers=[mcp_server]\n",
    "    )\n",
    "\n",
    "    with trace(\"account_manager\"):\n",
    "        result = await Runner.run(agent, request)\n",
    "    display(Markdown(result.final_output))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Building our own MCP Client"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from accounts_client import get_accounts_tools_openai, read_accounts_resource, list_accounts_tools\n",
    "\n",
    "mcp_tools = await list_accounts_tools()\n",
    "print(mcp_tools)\n",
    "openai_tools = await get_accounts_tools_openai()\n",
    "print(openai_tools)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "request = \"My name is Ian and my account is under the name Ian. What's my balance?\"\n",
    "\n",
    "with trace(\"account_mcp_client\"):\n",
    "    agent = Agent(\n",
    "        name=\"account_manager\", \n",
    "        instructions=instructions, \n",
    "        model=model, \n",
    "        tools=openai_tools\n",
    "    )\n",
    "    \n",
    "    result = await Runner.run(agent, request)\n",
    "    display(Markdown(result.final_output))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "context = await read_accounts_resource(\"Ian\")\n",
    "print(context)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Account.get(\"Ian\").report()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
